package com.neusoft.array;

/**
 * @author lichunlong lcl253137@alibaba-inc.com
 * @desc 用数组模拟栈的实现类
 * @date 2024-06-20
 */
public class ArrayStack {

    /**
     * 栈深
     */
    private int maxSize;

    /**
     * 数组模拟栈，数据就放在该数组
     */
    private int[] stack;

    /**
     * 栈顶
     */
    private int top = -1;

    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        stack = new int[maxSize];
    }

    /**
     * 判断栈是否已满
     *
     * @return 栈是否已满的标识
     */
    public boolean isFull() {
        return top == maxSize - 1;
    }

    /**
     * 入栈
     *
     * @param value 入栈的数据
     */
    public void push(int value) {
        if (isFull()) {
            System.out.println("栈已满");
            return;
        }
        top++;
        stack[top] = value;
    }

    /**
     * 判断栈是否为空
     *
     * @return 栈是否为空的标识
     */
    public boolean isEmpty() {
        return top == -1;
    }

    /**
     * 返回当前栈顶的值, 但是不是真正的pop
     */
    public int peek() {
        return stack[top];
    }

    /**
     * 出栈
     *
     * @return 出栈的数据
     */
    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("栈空，没有数据~");
        }
        int value = stack[top];
        top--;
        return value;
    }

    /**
     * 遍历打印栈中的数据
     */
    public void list() {
        if (isEmpty()) {
            System.out.println("栈空，没有数据~~");
            return;
        }
        // 需要从栈顶开始显示数据
        for (int i = top; i >= 0; i--) {
            System.out.printf("stack[%d]=%d\n", i, stack[i]);
        }
    }

    /**
     * 返回运算符的优先级，优先级使用数字表示: 数字越大，则优先级就越高
     *
     * @param operator 操作符
     * @return 优先级
     */
    public int getPriority(int operator) {
        if (operator == '*' || operator == '/') {
            return 1;
        } else if (operator == '+' || operator == '-') {
            return 0;
        } else {
            // 假定目前的表达式只有【+, - , * , /】
            return -1;
        }
    }

    /**
     * 判断是不是运算符
     *
     * @param val 操作符
     * @return 判断结果
     */
    public boolean isOperator(char val) {
        return val == '+' || val == '-' || val == '*' || val == '/';
    }

    /**
     * 计算方法
     *
     * @param num1     数字1
     * @param num2     数字2
     * @param operator 操作符
     * @return 计算结果
     */
    public int calc(int num1, int num2, int operator) {
        // res用于存放计算的结果
        int res = 0;
        switch (operator) {
            case '+':
                res = num1 + num2;
                break;
            case '-':
                // 注意顺序
                res = num2 - num1;
                break;
            case '*':
                res = num1 * num2;
                break;
            case '/':
                res = num2 / num1;
                break;
            default:
                break;
        }
        return res;
    }
}
